package org.smart.access.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.smart.access.dto.PageProp;
import org.smart.access.dto.UserInfo;
import org.smart.access.dto.UserRegister;
import org.smart.access.model.User;
import org.smart.access.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLException;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/register")
    @SaCheckLogin
    @SaCheckPermission(value = "住户",orRole = "0")
    public SaResult register(@RequestBody UserRegister userRegister) throws SQLException {
        log.debug("register user: {}", userRegister);
        // 手动鉴权, 用于判断是什么角色发送的请求, 避免使用注解鉴权时冗余的数据访问
        Long newUserId = null;
        if ("0".equals(StpUtil.getRoleList().get(0))) {
            newUserId = userService.register(userRegister, true);
        } else if ("业主".equals(StpUtil.getPermissionList().get(0))) {
            newUserId = userService.register(userRegister, false);
        } else {
            throw new NotPermissionException("权限不足");
        }
        return SaResult.data(userService.getInfo(newUserId));
    }

    @SaCheckLogin
    @PutMapping("/update")
    @SaCheckPermission(value = "业主", orRole = "0")
    public SaResult update(@RequestBody User user) {
        log.debug("update {}", user);
        // TODO: 权限验证, 业主只能修改居住在同一房屋的用户
        userService.updateById(user);
        return SaResult.ok();
    }

    /**
     * 使用密码登录
     * @param user 用户对象, 其中body参数为：phone, password
     * @return data: token值
     */
    @PostMapping("/login-pwd")
    public SaResult loginPwd(@RequestBody User user) {
        String phone = user.getPhone();
        String password = user.getPassword();
        if (phone == null || password == null) {
            return SaResult.error("用户名或密码不能为空");
        }
        Long userId = userService.loginWithPwd(phone, password);

        if (userId == null || userId == 0) {
            return SaResult.error("用户名或密码错误");
        } else {
            StpUtil.login(userId);
            return SaResult.data(StpUtil.getTokenValue());
        }
    }

    /**
     * 使用验证码登录
     * TODO: 计划实现
     */
    @RequestMapping("/login-code")
    public SaResult loginCode() {
        return SaResult.error("验证码登录暂未实现");
    }
    
    @GetMapping("/info")
    @SaCheckLogin
    public SaResult info() {
        Long userId = StpUtil.getLoginIdAsLong();
        UserInfo user = userService.getInfo(userId);
        return SaResult.data(user);
    }

    @GetMapping("/is-logined")
    public SaResult isLogined() {
        if(StpUtil.isLogin()) return SaResult.ok();
        return SaResult.notLogin();
    }

    @PostMapping("/mlist")
    @SaCheckLogin
    @SaCheckRole("0")
    public SaResult mlist(@RequestBody PageProp<User, Void> pageProp) {
        log.debug("/user/mlist: {}", pageProp);
        IPage<UserInfo> page = userService.getMUserList(pageProp);
        return SaResult.data(page);
    }

    @DeleteMapping("/delete/{uid}")
    @SaCheckLogin
    @SaCheckPermission(value = "业主", orRole = "0")
    public SaResult delete(@PathVariable("uid") Long uid) {
        log.debug("/user/delete: {}", uid);
        // TODO: 权限验证, 业主只能修改居住在同一房屋的用户
        userService.removeById(uid);
        return SaResult.ok();
    }
}
